package com.happy.xiao.common.rabbitmq.service.impl;

import com.happy.xiao.common.rabbitmq.bean.MessageReliabilityDelay;
import com.happy.xiao.common.rabbitmq.bean.MessageSend;
import com.happy.xiao.common.rabbitmq.service.ICommonMessage;
import com.happy.xiao.common.utils.Util;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.UnsupportedEncodingException;
import java.util.UUID;

@Service("CommonMessageService")
public class CommonMessageImpl implements ICommonMessage {

    @Autowired
    private Environment env;

    // TODO ------------------------------------------------------------------------------------------------------------
    // TODO ---------------------------------------------普通消息--------------------------------------------------------
    // TODO ------------------------------------------------------------------------------------------------------------

    /**
     * 发送普通消息【消息id自动生成】
     *
     * @param rabbitTemplate
     * @param exchange
     * @param routingKey
     * @param message
     * @return
     * @throws Exception
     */
    @Override
    public boolean sendNormal(RabbitTemplate rabbitTemplate,
                              String exchange,
                              String routingKey,
                              String message) throws Exception {
        return createNormalMessage(rabbitTemplate, exchange, routingKey, message, null);
    }

    /**
     * 发送普通消息【消息id自动生成】
     *
     * @param rabbitTemplate
     * @param exchange
     * @param routingKey
     * @param object
     * @param <T>
     * @return
     * @throws Exception
     */
    @Override
    public <T> boolean sendNormal(RabbitTemplate rabbitTemplate,
                                  String exchange,
                                  String routingKey,
                                  T object) throws Exception {
        String jsonStr = Util.ObjectToJson(object);
        return createNormalMessage(rabbitTemplate, exchange, routingKey, jsonStr, null);
    }

    /**
     * 发送普通消息
     *
     * @param rabbitTemplate
     * @param exchange
     * @param routingKey
     * @param message
     * @param messageId
     * @return
     * @throws Exception
     */
    @Override
    public boolean sendNormal(RabbitTemplate rabbitTemplate,
                              String exchange,
                              String routingKey,
                              String message,
                              String messageId) throws Exception {
        return createNormalMessage(rabbitTemplate, exchange, routingKey, message, messageId);
    }

    /**
     * 发送普通消息
     *
     * @param rabbitTemplate
     * @param exchange
     * @param routingKey
     * @param object
     * @param messageId
     * @param <T>
     * @return
     * @throws Exception
     */
    @Override
    public <T> boolean sendNormal(RabbitTemplate rabbitTemplate,
                                  String exchange,
                                  String routingKey,
                                  T object,
                                  String messageId) throws Exception {
        String jsonStr = Util.ObjectToJson(object);
        return createNormalMessage(rabbitTemplate, exchange, routingKey, jsonStr, messageId);
    }

    /**
     * 创建普通消息
     *
     * @param rabbitTemplate
     * @param exchange
     * @param routingKey
     * @param message
     * @param messageId
     * @return
     */
    private boolean createNormalMessage(RabbitTemplate rabbitTemplate,
                                        String exchange,
                                        String routingKey,
                                        String message,
                                        String messageId) {
        try {
            rabbitTemplate.setExchange(exchange);
            rabbitTemplate.setRoutingKey(routingKey);

            // 如果这个没有消息id,则自动生成
            if (StringUtils.isEmpty(messageId)) messageId = createMessageID();

            byte[] messageByte = message.getBytes("UTF-8");

            Message msg = MessageBuilder
                    .withBody(messageByte)
                    .setDeliveryMode(MessageDeliveryMode.PERSISTENT)
                    .setMessageId(messageId)
                    .build();

            MessageSend temp = new MessageSend(messageId, exchange, routingKey, message);
            String tempStr = Util.ObjectToJson(temp);
            CorrelationData correlationData = new CorrelationData(tempStr);
            rabbitTemplate.correlationConvertAndSend(msg, correlationData);
            return true;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return false;
        }
    }



    // TODO ------------------------------------------------------------------------------------------------------------
    // TODO ---------------------------------------------延时消息--------------------------------------------------------
    // TODO ------------------------------------------------------------------------------------------------------------


    /**
     * 发送延时消息【消息id自动生成】
     *
     * @param rabbitTemplate
     * @param exchange
     * @param routingKey
     * @param message
     * @param times          延迟时间 单位毫秒
     * @return
     * @throws Exception
     */
    @Override
    public boolean sendDelay(RabbitTemplate rabbitTemplate,
                             String exchange,
                             String routingKey,
                             String message,
                             long times) throws Exception {
        return createDelayMessage(rabbitTemplate, exchange, routingKey, message, null, times);
    }

    /**
     * 发送延时消息【消息id自动生成】
     *
     * @param rabbitTemplate
     * @param exchange
     * @param routingKey
     * @param object
     * @param times          单位毫秒
     * @param <T>
     * @return
     * @throws Exception
     */
    @Override
    public <T> boolean sendDelay(RabbitTemplate rabbitTemplate,
                                 String exchange,
                                 String routingKey,
                                 T object,
                                 long times) throws Exception {
        String jsonStr = Util.ObjectToJson(object);
        return createDelayMessage(rabbitTemplate, exchange, routingKey, jsonStr, null, times);
    }

    /**
     * 发送延时消息
     *
     * @param rabbitTemplate
     * @param exchange
     * @param routingKey
     * @param message
     * @param messageId
     * @param times          单位毫秒
     * @return
     * @throws Exception
     */
    @Override
    public boolean sendDelay(RabbitTemplate rabbitTemplate,
                             String exchange,
                             String routingKey,
                             String message,
                             String messageId,
                             long times) throws Exception {
        return createDelayMessage(rabbitTemplate, exchange, routingKey, message, messageId, times);
    }

    /**
     *  发送延时消息
     * @param rabbitTemplate
     * @param exchange
     * @param routingKey
     * @param object
     * @param messageId
     * @param times      单位毫秒
     * @param <T>
     * @return
     * @throws Exception
     */
    @Override
    public <T> boolean sendDelay(RabbitTemplate rabbitTemplate,
                                 String exchange,
                                 String routingKey,
                                 T object,
                                 String messageId,
                                 long times) throws Exception {
        String jsonStr = Util.ObjectToJson(object);
        return createDelayMessage(rabbitTemplate, exchange, routingKey, jsonStr, messageId, times);
    }




    /**
     * 延时消息
     *
     * @param rabbitTemplate
     * @param exchange
     * @param routingKey
     * @param message
     * @param messageId
     * @param time
     * @return
     */
    private boolean createDelayMessage(RabbitTemplate rabbitTemplate,
                                       String exchange,
                                       String routingKey,
                                       String message,
                                       String messageId,
                                       long time) {
        try {
            rabbitTemplate.setExchange(exchange);
            rabbitTemplate.setRoutingKey(routingKey);

            // 如果这个没有消息id,则自动生成
            if (StringUtils.isEmpty(messageId)) messageId = createMessageID();
            byte[] messageByte = message.getBytes("UTF-8");

            Message msg = MessageBuilder
                    .withBody(messageByte)
                    .setDeliveryMode(MessageDeliveryMode.PERSISTENT)
                    .setMessageId(messageId)
                    .build();

            // 这里设置延时消息
            if (time != 0) msg.getMessageProperties().setExpiration(String.valueOf(time));  // 毫秒

            MessageSend temp = new MessageSend(messageId, exchange, routingKey, message);
            String tempStr = Util.ObjectToJson(temp);
            CorrelationData correlationData = new CorrelationData(tempStr);
            rabbitTemplate.correlationConvertAndSend(msg, correlationData);
            return true;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return false;
        }
    }

    // TODO ------------------------------------------------------------------------------------------------------------
    // TODO ---------------------------------------------可靠消息--------------------------------------------------------
    // TODO ------------------------------------------------------------------------------------------------------------

//    @Override
//    public boolean sendReliabilityCheckDelayMessage(RabbitTemplate rabbitTemplate, MessageReliabilityDelay object) throws Exception {
//
//
//
//        return false;
//    }
//
//    /**
//     * 消息消费确认机制  【可靠性信息】
//     *
//     * @param rabbitTemplate
//     * @param message 消息内容
//     * @return
//     * @throws Exception
//     */
//    @Override
//    public boolean sendReliabilityConfirmMessage(RabbitTemplate rabbitTemplate,
//                                                 String message) throws Exception {
//        String exchange = env.getProperty("check.confirm.exchange.name");
//        String routingKey = env.getProperty("check.confirm.routing.key.name");
//        return sendNormal(rabbitTemplate, exchange, routingKey, message);
//    }
//
//    @Override
//    public boolean sendReliabilityNormalMessage(RabbitTemplate rabbitTemplate,
//                                                String exchange,
//                                                String routingKey,
//                                                String message,
//                                                String callbackUrl) throws Exception {
//
//
//
//
//        return false;
//    }




    // TODO ------------------------------------------------------------------------------------------------------------
    // TODO ---------------------------------------------其他内容--------------------------------------------------------
    // TODO ------------------------------------------------------------------------------------------------------------

    @Override
    public String createMessageID(String key) {
        if (StringUtils.isEmpty(key)) {
            return createMessageID();
        }
        return key + "-" + System.currentTimeMillis() + "-" + UUID.randomUUID() + "";
    }

    @Override
    public String createMessageID() {
        return System.currentTimeMillis() + "-" + UUID.randomUUID() + "";
    }


}
